#ifndef SERVER_H
#define SERVER_H

#include "room_global.h"
#include <boost/noncopyable.hpp>
#include <boost/thread.hpp>
#include <boost/pool/pool.hpp>

class Setting;
class EventFactory;
class EventQueue;
class EventDispatcher;
class TimerService;
class NetService;
class DatabaseService;
class AsyncService;
class DatabaseAssist;
class NetworkAssist;

class Server :
        protected boost::noncopyable
{
public:
    typedef boost::thread_group ThreadPool;
    typedef boost::pool<> MemoryAllocator;
    typedef boost::shared_ptr< Setting > SettingPtr;
    typedef boost::shared_ptr< EventFactory > EventFactoryPtr;
    typedef boost::shared_ptr< EventQueue > EventQueuePtr;
    typedef boost::shared_ptr< EventDispatcher > EventDispatcherPtr;

    typedef boost::shared_ptr< TimerService > TimerServicePtr;
    typedef boost::shared_ptr< NetService > NetServicePtr;
    typedef boost::shared_ptr< DatabaseService > DatabaseServicePtr;
    typedef boost::shared_ptr< AsyncService > AsyncServicePtr;

    typedef boost::shared_ptr< DatabaseAssist > DatabaseAssistPtr;
    typedef boost::shared_ptr< NetworkAssist > NetworkAssistPtr;

public:
    Server();
    ~Server();

    // Server setting data
    const SettingPtr &settings();

    // Memory manager
    void *allocMemory(size_t n);
    bool freeMemory(void *p, size_t n);

    // Event components
    const EventFactoryPtr &eventFactory();
    const EventQueuePtr &eventQueue();
    const EventDispatcherPtr &eventDispatcher();

    // Asynchronous service core
    const TimerServicePtr &timerService();
    const NetServicePtr &netService();
    const DatabaseServicePtr &dbService();
    const AsyncServicePtr &asyncService();

    // Assist and functional.
    const DatabaseAssistPtr &dbAssist();
    const NetworkAssistPtr &netAssist();

public:
    int start(int argc, char **argv);
protected:
    bool parseCommandLine(int argc, char **argv);
    bool initialize();
    int  run();

    bool initSettings();
    bool initEventComponents();
    bool initServices();
    bool initAssists();

    bool startNetwork();
    int  startThreads();
    void routine();

private:
    SettingPtr m_setting;

    EventFactoryPtr m_eventFactory;

    EventQueuePtr m_eventQueue;

    EventDispatcherPtr m_eventDispatcher;

    TimerServicePtr m_timerService;

    NetServicePtr m_netService;

    DatabaseServicePtr m_dbService;

    AsyncServicePtr m_service;

    NetworkAssistPtr m_netAssist;

    DatabaseAssistPtr m_dbAssist;

    ThreadPool m_threads;

    MemoryAllocator m_memoryAllocator;
};

#endif // SERVER_H
